home *** CD-ROM | disk | FTP | other *** search
/ TOS Silver 2000 / TOS Silver 2000.iso / programm / GNUC / UTIL-41S.LZH / util-41 / cnm.c < prev    next >
Encoding:
C/C++ Source or Header  |  1998-10-05  |  7.5 KB  |  418 lines

  1. /* Copyright (c) 1988 by Sozobon, Limited.  Author: Johann Ruegg
  2.  *
  3.  * Permission is granted to anyone to use this software for any purpose
  4.  * on any computer system, and to redistribute it freely, with the
  5.  * following restrictions:
  6.  * 1) No charge may be made other than reasonable charges for reproduction.
  7.  * 2) Modified versions must be clearly marked as such.
  8.  * 3) The authors are not responsible for any harmful consequences
  9.  *    of using this software, even if they result from defects in it.
  10.  *
  11.  *    Alternative ST symbol table lister.
  12.  */
  13.  
  14. /* highly munged from above, VERY quick and dirty nm, just enough
  15.    here to find _stksize for fixstk.c and printstk.c, may be
  16.    useful for other stuff.
  17.  
  18.    WARNING: -g option will not work with gcc-ld produced a.out
  19.  
  20.  
  21.      ++jrb
  22.  */
  23.  /*
  24.  * Modified to handle expanded, GST linker derived, format for symbols.
  25.  * This format is produced with -G flag to a proper version of gcc-ld.
  26.  * -g flag also will work if ld coached properly.
  27.  *
  28.  *   --mj
  29.  */
  30.  
  31. /*
  32.  * ++jrb rework and cleanup while adding A_TFILE A_TFARC
  33.  */
  34.  
  35. #include <stdio.h>
  36. #include <stdlib.h>
  37.  
  38. #ifdef CROSSATARI
  39. #include "cross-inc/compiler.h"
  40. #include "cross-inc/st-out.h"
  41. #else
  42. #include <compiler.h>
  43. #include <st-out.h>
  44. #endif
  45.  
  46. #ifdef BYTE_SWAP
  47. #define SWAP4(y) (((unsigned)(y)>>24) + (((unsigned)(y)>>8)&0xff00) + \
  48.          (((unsigned)(y)<<8)&0xff0000) + ((unsigned)(y)<<24)) 
  49. #define SWAP2(y) ((((unsigned)(y)&0xff00)>>8) + (((unsigned)(y)&0x00ff)<<8))
  50. #endif /* BYTE_SWAP */
  51.  
  52. #ifndef WORD_ALIGNED
  53. # define SIZEOF_SYM ((size_t)sizeof(struct asym))
  54. #else
  55. # define SIZEOF_SYM ((size_t)14)
  56. #endif
  57.  
  58. #ifdef atarist
  59. #define READB    "rb"
  60. #else
  61. #define READB "r"
  62. #endif
  63.  
  64. struct xsym {
  65.     char name[8];
  66.     union {
  67.     unsigned char  _flags[2];
  68.     unsigned short _sflgs;
  69.     } u;
  70.     unsigned long value;
  71.     char tail[SIZEOF_SYM];
  72. };
  73.  
  74. #define flags    u._flags[0]
  75. #define xflags  u._flags[1]
  76. #define sflgs   u._sflgs
  77.  
  78. #ifdef __STDC__
  79. # define P(s) s
  80. #else
  81. # define P(s) ()
  82. #endif
  83.  
  84. int main P((int argc , char **argv ));
  85. int cmp P((struct xsym *s1 , struct xsym *s2 ));
  86. int doname P((char *s , int many ));
  87. long dohdr P((FILE *fd ));
  88. void dosym P((struct xsym *s ));
  89. int not_glob P((unsigned int x ));
  90. void sflags P((struct xsym *s ));
  91. void ckfread P((void *buf , int siz , int n , FILE *fp ));
  92. long readhead P((struct aexec *h , int n , FILE *fd ));
  93. int readsyms P((struct xsym *syms , int n , FILE *fd ));
  94. void usage P((void ));
  95.  
  96. #undef P
  97.  
  98. extern void dump_version(char *prog);
  99. char *progname = "cnm";
  100.  
  101. int gflag;
  102. int uflag;
  103.  
  104. int main(argc, argv)
  105. int argc;
  106. char **argv;
  107. {
  108.     int c, status = 0;
  109.     extern char *optarg;
  110.     extern int optind;
  111.     
  112.     if (argv[0][0] != '\0')
  113.       progname = argv[0];
  114.  
  115.     while ((c = getopt(argc, argv, "guv")) != -1)
  116.     switch (c)
  117.     {
  118.       case 'g':
  119.         gflag = 1;
  120.         break;
  121.       case 'u':
  122.         uflag = 1;
  123.         break;
  124.       case 'v' :
  125.            dump_version(progname);
  126.            exit(0);
  127.            break;
  128.       case '?':
  129.         usage();
  130.     }
  131.     c = argc - optind;
  132.     if(c <= 0)
  133.     usage();
  134.     
  135.     for (; optind < argc; optind++) 
  136.     status |= doname(argv[optind], (c > 1));
  137.     return status;
  138. }
  139.  
  140. int  cmp(s1, s2)
  141. struct xsym *s1, *s2;
  142. {
  143.   long diff = s1->value - s2->value;
  144.   return (diff > 0) - (diff < 0);
  145. }
  146.  
  147. int doname(s, many)
  148. char *s;
  149. int many;
  150. {
  151.     FILE *fd, *fopen();
  152.     long i, count;
  153.  
  154.     if(!(fd = fopen(s, READB)))
  155.     {
  156.     perror(s);
  157.     return 2;
  158.     }
  159.     if (many)
  160.     printf("\n%s:\n", s);
  161.  
  162.     if (i = dohdr(fd))
  163.     {
  164.     struct xsym *syms, *savesyms;
  165.     struct xsym *currsym;
  166.     printf("%ld slots mem %ld\n", i, (long)(i*sizeof(struct xsym)));
  167.     
  168.     if((savesyms = syms = (struct xsym *)malloc(i*sizeof(struct xsym))) == NULL)
  169.     {
  170.         perror("Outa mem");
  171.         exit(4);
  172.     }
  173.     count = i;
  174.     currsym = syms;
  175.     while (count)
  176.     {
  177.         if(readsyms(currsym, 1, fd) != 1)
  178.         {
  179.         perror("reading syms");
  180.         exit(8);
  181.         }
  182.         if (--count)
  183.         {
  184.         if (A_LNAM == (currsym->xflags & A_LNAM))
  185.         {
  186.             if(fread(currsym->tail, SIZEOF_SYM, 1, fd) != 1)
  187.             {
  188.             perror("reading syms");
  189.             exit(16);
  190.             }
  191.             --i;
  192.             --count;
  193.         }
  194.         }
  195.         else /* object was partially stripped */
  196.         currsym->xflags &= ~A_LNAM;        
  197.         if (gflag && not_glob((unsigned int)(currsym->flags)))
  198.         --i;
  199.         else
  200.         currsym++;
  201.     }
  202.     fclose(fd);
  203.     printf("%ld %s symbol(s)\n", i, (gflag ? "global ": ""));
  204.     if (!uflag)
  205.       qsort(syms, i, sizeof(struct xsym), cmp);
  206.     while (i--)
  207.     {
  208.         dosym(syms);
  209.         syms += 1;
  210.     }
  211.     free(savesyms);
  212.     }
  213.     return 0;
  214. }
  215.  
  216. long dohdr(fd)
  217. FILE *fd;
  218. {
  219.     struct aexec h;
  220.     long i;
  221.         
  222.     i = readhead(&h, 1, fd);
  223.     if (i != 1 || h.a_magic != CMAGIC)
  224.     {
  225.     fprintf(stderr, "Bad header\n");
  226.     return 0L;
  227.     }
  228.     fseek(fd, (h.a_text + h.a_data), 1);
  229.     return h.a_syms / SIZEOF_SYM;
  230. }
  231.  
  232. void
  233. dosym(s)
  234. struct xsym *s;
  235. {
  236.     printf("%-8.8s", s->name);
  237.     printf("%-14.14s", (A_LNAM == (s->xflags & A_LNAM) ? s->tail : ""));
  238.     printf("\t%8lx ", s->value);
  239.     s->xflags &= ~A_LNAM;
  240.     sflags(s);
  241.     putchar('\n');
  242. }
  243.  
  244. char *fname[] = {
  245.     "?0?", " bss", " text", "?3?", " data",
  246.     "?5?", "?6?", "?7?"
  247. };
  248. char *Fname[] = {
  249.     "?0?", "Bss", "Text", "?3?", "Data",
  250.     "?5?", "?6?", "?7?"
  251. };
  252.  
  253. int not_glob(x)
  254. unsigned int x;
  255. {
  256.     x &= 0xff;
  257.     if (x & 0x20)
  258.         return 0;
  259.     x &= ~0x20;
  260.     if (x == 0x88)
  261.         return 0;
  262.     return 1;
  263. }
  264.  
  265. void
  266. sflags(s)
  267. struct xsym *s;
  268. {
  269.     unsigned int x = s->flags;
  270.     char **category;
  271.     int lflag;
  272.     
  273.     if(s->sflgs == A_TFILE)
  274.     printf("text file");
  275.     else if (s->sflgs == A_TFARC)
  276.     printf("text file archive");
  277.     else
  278.     {
  279.     if (0 != (lflag = not_glob(x)))
  280.         category = fname;
  281.     else
  282.         category = Fname;
  283.  
  284.     x &= 0xff;
  285.     if (x & 0x20)
  286.         printf("global ");
  287.     x &= ~0x20;
  288.     if (x & 0xd8)
  289.     {
  290.         if (x & 0x08)
  291.         printf (" external");
  292.         if (x & 0x50)
  293.         {
  294.         printf (" equ");
  295.         if (x & 0x10)
  296.             printf (" reg");
  297.         }
  298.         if (x & 0x80)
  299.         printf (" abs");
  300.         if (!lflag)
  301.         printf(" G");
  302.     }
  303.     else
  304.     {
  305.         x &= 7;
  306.         printf(category[x]);
  307.     }
  308.     }
  309.     printf(" (0x%04x)",(unsigned int)(s->sflgs));
  310. }
  311.  
  312. void ckfread(buf, siz, n, fp)
  313. void *buf;
  314. int siz, n;
  315. FILE *fp;
  316. {
  317.     if(fread(buf, siz, n, fp) != n)
  318.     {
  319.         perror("reading");
  320.         exit(32);
  321.     }
  322. }
  323.  
  324. long readhead(h, n, fd)
  325. struct aexec *h;
  326. int n;
  327. FILE *fd;
  328. {
  329.     short i;
  330.     long j;
  331.     int k;
  332.  
  333.     for(k = 0; k < n; k++)
  334.     {
  335.     ckfread(&i, 2, 1, fd);
  336.     h->a_magic = i;
  337.     ckfread(&j, 4, 1, fd);
  338.     h->a_text = j;
  339.     ckfread(&j, 4, 1, fd);
  340.     h->a_data = j;
  341.     ckfread(&j, 4, 1, fd);
  342.     h->a_bss = j;
  343.     ckfread(&j, 4, 1, fd);
  344.     h->a_syms = j;
  345.     ckfread(&j, 4, 1, fd);
  346.     h->a_AZero1 = j;
  347.     ckfread(&j, 4, 1, fd);
  348.     h->a_ldflgs = j;
  349.     ckfread(&i, 2, 1, fd);
  350.     h->a_isreloc = i;
  351.     }
  352. #ifdef BYTE_SWAP
  353.     h->a_magic = SWAP2(h->a_magic);
  354.     h->a_text = SWAP4(h->a_text);
  355.     h->a_data = SWAP4(h->a_data);
  356.     h->a_bss = SWAP4(h->a_bss);
  357.     h->a_syms = SWAP4(h->a_syms);
  358.     h->a_AZero1 = SWAP4(h->a_AZero1);;
  359.     h->a_ldflgs = SWAP4(h->a_ldflgs);;
  360.     h->a_isreloc = SWAP2(h->a_isreloc);;
  361. #endif
  362.     return k;
  363. }
  364.  
  365. int readsyms(syms, n, fd)
  366. struct xsym *syms;
  367. int n;
  368. FILE *fd;
  369. {
  370.     int k;
  371.  
  372.     for(k = 0; k < n; k++, syms++)
  373.     {
  374.     ckfread(syms->name, 8, 1, fd);
  375.     ckfread(&(syms->sflgs), 2, 1, fd);
  376.     ckfread(&(syms->value), 4, 1, fd);
  377. #ifdef BYTE_SWAP
  378. /*
  379.     syms->sflgs = SWAP2(syms->sflgs);
  380. */
  381.     syms->value = SWAP4(syms->value);
  382. #endif
  383.  
  384.    }
  385.    return k;
  386. }
  387.  
  388. void usage()
  389. {
  390.      dump_version(progname);
  391.     fprintf(stderr, "cnm [-g] files...\n");
  392.     exit(1);
  393. }
  394.  
  395. #if !defined(__GNUC__) &&  defined(hpux)
  396.  
  397. char *xmalloc(n)
  398. int n;    /* sigh! */
  399. {
  400.    char *ret = (char *)malloc(n);
  401.  
  402.    if(ret) return ret;
  403.    perror("malloc");
  404.    exit(1);
  405. }
  406.  
  407. char *xrealloc(b, n)
  408. char * b;
  409. int n;    /* sigh! */
  410. {
  411.    char *ret = (char *)realloc(b, n);
  412.  
  413.    if(ret) return ret;
  414.    perror("realloc");
  415.    exit(2);
  416. }
  417. #endif
  418.